﻿Imports Microsoft.DirectX
Imports Microsoft.DirectX.Direct3D
Imports System.Drawing
Imports System.Drawing.Imaging
Public Class Grafikengine
#Region "Variablen"
    'Sprite Objekt
    ''' <summary>
    ''' Die Sprites werden von hier in den Backpuffer gezeichnet
    ''' </summary>
    Public Shared Sprite As Direct3D.Sprite
    'Hier stehen Texturen
    ''' <summary>
    ''' Textur Ausschnitt
    ''' </summary>
    ''' <remarks></remarks>
    Public Shared recBild As Drawing.Rectangle
    ''' <summary>
    ''' Skalierung
    ''' </summary>
    ''' <remarks></remarks>
    Public Shared szfScale As Drawing.Size
    ''' <summary>
    ''' Rotatationszentrum 0,0 ist die obere Ecke des Bildes 
    ''' </summary>
    ''' <remarks></remarks>
    Public Shared ptfRotCenter As Drawing.Point
    ''' <summary>
    ''' Position von der aus gezeichnet wird
    ''' </summary>
    ''' <remarks></remarks>
    Public Shared ptfPosition As Drawing.Point


    ''' <summary>
    ''' Der Device stellt die Grafikkarte dar
    ''' </summary>
    ''' 
    Public Shared Grafikkarte As Device = Nothing
    ''' <summary>
    ''' Parameter der Grafikkarte.
    ''' </summary>
    ''' <remarks></remarks>
    Public Shared _presentParameter As PresentParameters
    ''' <summary>
    ''' Der Boolen der angibt ob wir alles in ein Fenster zeichnen
    ''' </summary>
    ''' <remarks></remarks>
    Public Shared IneinemFenster As Boolean = False
    Public Shared SCREENWIDTH As Single = 800
    Public Shared SCREENHEIGHT As Single = 600
    Public Shared Verwalter As Objektverwalter
    Public Shared PI As Single
    Private Shared FilledTexture As Texture

    Public Shared Lichtfarbe As Color = Color.White
    Shared Ambientfarbe As Color = Color.FromArgb(0, 50, 50, 50)
    Public Shared DeviceLost As Boolean = False
#End Region

#Region "Laden"
    ''' <summary>
    ''' Gibt unserer Grafikkarte die passende auflösung
    ''' </summary>
    ''' <param name="Breite">Die Breite des Bildschirms(800,1024,1280)</param>
    ''' <param name="Höhe">Die Höhe des Bildschrims(600,768,800)</param>
    ''' <param name="InFensterrendern">Sagt ob das Bild in einem Fenster oder auf dem Bildschirm gezeichnet wird</param>
    Public Sub New(ByVal Breite As Integer, ByVal Höhe As Integer, ByVal HM As Control, ByVal InFensterrendern As Boolean)
        'Hier werden Konstanten festgelegt
        SetPI()
        SCREENWIDTH = Breite
        SCREENHEIGHT = Höhe
        IneinemFenster = InFensterrendern
        If IneinemFenster = True Then
            HM.Width = Breite
            HM.Height = Höhe
        End If
        'DirectX initialisieren
        If Initialization(HM) = False Then
            MsgBox("DirectX couldn't be initialized. Try to reset the settings. (Click at ""help!"" at the CommanderWars launcher", MsgBoxStyle.Critical, "Fatal Error!")
        End If
        'Direct3D Font Objekt erzeugen

        'Texture laden

        Try
            Dim Pfad As String = My.Settings.Resourcenpfad + "Rectancle.png"
            Dim Bild As Bitmap = Image.FromFile(Pfad)
            FilledTexture = TextureLoader.FromFile(Grafikkarte, Pfad, Bild.Width, Bild.Height, 0, 0, Format.A8B8G8R8, Pool.Managed, Filter.None, Filter.None, &HFF000111)
        Catch
        End Try

        'If LoadTexture() = False Then
        '    MessageBox.Show("Die Texture konnte nicht geladen werden. Das Beispiel wird beendet.")
        '    Return False
        'End If
    End Sub
    Public Shared Sub NeuLaden(ByVal Breite As Integer, ByVal Höhe As Integer, ByVal HM As Control, ByVal InFensterrendern As Boolean)
        'Hier werden Konstanten festgelegt
        SetPI()
        SCREENWIDTH = Breite
        SCREENHEIGHT = Höhe
        IneinemFenster = InFensterrendern
        'DirectX initialisieren
        If Initialization(HM) = False Then

        End If
        'Direct3D Font Objekt erzeugen

        'Texture laden

        'If LoadTexture() = False Then
        '    MessageBox.Show("Die Texture konnte nicht geladen werden. Das Beispiel wird beendet.")
        '    Return False
        'End If
    End Sub
    Private Shared Function Initialization(ByVal HM As Control) As Boolean
        
        _presentParameter = CreatePresentParameters()
        'Device erstellen falls keiner vorhanden...
        If Grafikkarte Is Nothing Then Grafikkarte = New Device(0, DeviceType.Hardware, HM, CreateFlags.HardwareVertexProcessing, _presentParameter) 'CreateFlags.SoftwareVertexProcessing
        ' Grafikkarte.RenderState.ZBufferEnable = True
        'Sprite Objekt erstellen
        Sprite = New Direct3D.Sprite(Grafikkarte)
        Schriftengine.Sprite2 = New Direct3D.Sprite(Grafikkarte)


        If My.Settings.draw3D Then
            'Noch ein paar 3D sachen
            With Grafikkarte.RenderState
                .Lighting = True
                .FillMode = FillMode.Solid
                .ZBufferEnable = True
                .AntiAliasedLineEnable = True
                .MultiSampleAntiAlias = True
                .DitherEnable = True
                .NormalizeNormals = True
                .SpecularEnable = True
                .ShadeMode = ShadeMode.Gouraud

                ''Nebel machen...
                '.FogStart = 20
                '.FogEnd = 200
                '.FogColor = Color.Lime
                '.FogTableMode = FogMode.Linear
                '.FogEnable = Nebel
            End With
            'ein paar Irrlichter...
            Grafikkarte.Lights(0).Type = LightType.Directional
            Grafikkarte.Lights(0).Position = New Vector3(0, 0, 0)
            Grafikkarte.Lights(0).Direction = New Vector3(0, -1, 0.1)
            Grafikkarte.Lights(0).Diffuse = Lichtfarbe
            Grafikkarte.Lights(0).Ambient = Ambientfarbe
            Grafikkarte.Lights(0).Attenuation0 = 0.2
            Grafikkarte.Lights(0).Range = 1000
            Grafikkarte.Lights(0).Enabled = True

            Grafikkarte.Lights(0).Update()

            Grafikkarte.Lights(1).Ambient = Color.White
            Grafikkarte.Lights(1).Type = LightType.Point
            'Noch zu den Lichtern, alles was ich weiß, oder zu wissen glaube...
            'Ambient: Ein Licht das generell, überall und egal wo ist. (reflektiertes licht; also einfach, dass nicht alles schwarz ist, sondern dass es eben einfach zusätzlich etwas licht gibt.
            'Ambient Color

            'Directional: Naja, im Grunde wie ambient, nur dass es hier auf die richtung ankommt.
            'Type
            'Diffuse
            'Range
            'Direction



            Dim M As New Material
            'M.Ambient = Color.White
            M.Emissive = Color.White
            ' M.Diffuse = Color.White
            Mat = M
            'die kleine Box, zur Intersection..
            Box = Mesh.Box(Grafikkarte, 1, 0.001, 1)
        End If
        Grafikkarte.Transform.Projection = Matrix.PerspectiveFovLH(Math.PI / 4, Hauptmenü.MainMenü.MalPanel.Width / Hauptmenü.MainMenü.MalPanel.Height, 0.1, 10000)
        Return True
    End Function
    ''' <summary>
    ''' This Sub creates the Basic Presentparameters
    ''' </summary>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Private Shared Function CreatePresentParameters() As PresentParameters
        Dim P As New PresentParameters
        'festlegen der Darstellungs-Parameter (present)
        P.Windowed = IneinemFenster 'Darstellung im Vollbild
        P.SwapEffect = SwapEffect.Discard ' SwapEffect.Flip
        P.BackBufferCount = 1
        P.BackBufferWidth = SCREENWIDTH
        P.BackBufferHeight = SCREENHEIGHT
        P.BackBufferFormat = Format.R5G6B5

        '|---------------> zusätzlich
        P.PresentationInterval = PresentInterval.Immediate
        P.AutoDepthStencilFormat = DepthFormat.D16
        P.EnableAutoDepthStencil = True
        'zusätzlich  <---------------| 
        P.DeviceWindow = Hauptmenü.MainMenü.MalPanel
        Return P
    End Function
    Private Shared Sub SetPI()
        PI = Math.Atan(1) * 4
    End Sub
    ''' <summary>
    ''' Noch in Arbeit
    ''' </summary>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Shared Function LoadTexture(ByVal Pfad As String) As Texture
        If Grafikkarte IsNot Nothing Then
            Dim neueTexture As Texture

            If Not My.Computer.FileSystem.FileExists(Pfad) Then Return Nothing
            Dim Bild As Bitmap = Image.FromFile(Pfad)
            'Texture laden
            neueTexture = TextureLoader.FromFile(Grafikkarte, Pfad, Bild.Width, Bild.Height, 0, 0, Format.A8B8G8R8, Pool.Managed, Filter.None, Filter.None, &HFF000000)
            Return neueTexture
        Else
            Return Nothing
        End If
    End Function
    Public Shared Function LoadTexture(ByVal Bild As Bitmap)
        If Grafikkarte IsNot Nothing Then
            Dim neueTextur As Texture = Texture.FromBitmap(Grafikkarte, Bild, Usage.None, Pool.Managed)
            Return neueTextur
        Else
            Return Nothing
        End If
    End Function
    Public Shared Function LoadTexture(ByVal Bild As Image, ByVal Farbtabelle As Bitmap) As Texture
        Bild = Grafikengine.Bildverändern(Bild, My.Resources.Neutral, 0, 0, Farbtabelle)
        Dim neueTextur As Texture = Texture.FromBitmap(Grafikkarte, Bild, Usage.None, Pool.Managed)
        Return neueTextur
    End Function
    Public Shared Function LoadTexture(ByVal Bild As Image, ByVal StartFarbtabelle As Bitmap, ByVal EndFarbtabelle As Bitmap) As Texture
        Bild = Grafikengine.Bildverändern(Bild, StartFarbtabelle, 0, 0, EndFarbtabelle)
        Dim neueTextur As Texture = Texture.FromBitmap(Grafikkarte, Bild, Usage.None, Pool.Managed)
        Return neueTextur
    End Function
    Public Shared Function LoadTexture(ByVal Bild As Image, ByVal Hue As Single) As Texture
        Bild = Farbwertverädern(Bild, Hue)
        Dim neueTextur As Texture = Texture.FromBitmap(Grafikkarte, Bild, Usage.None, Pool.Managed)
        Return neueTextur
    End Function
    Private Shared Function DegToRad(ByVal Degrees As Double) As Single
        DegToRad = Degrees / 180 * PI
    End Function
    Private Shared Function RadToDeg(ByVal Radians As Double) As Single
        RadToDeg = Radians * 180 / PI
    End Function
#End Region

#Region "Malen"
#Region "Device wiederkriegen"
    Public Shared Sub AttemptRecovery()
        ' when we lose the device, this code will run

        Try
            Grafikkarte.TestCooperativeLevel()  'Test for Exclusive control; if it's lacking, it'll throw
        Catch e As DeviceLostException     'DeviceLostException. If it does, we just wait until
            'Failed.                       'our game is given the focus again.
        Catch e As DeviceNotResetException  'If we have the focus, we only need to reset the device:

            ' Basically we re-do what we did in initialize graphics
            Try
                'Here, you need to destroy everything in Pool_Default, and all instances of the
                ' swapchain class.
                Dim P As PresentParameters = CreatePresentParameters()
                Grafikkarte.Reset(_presentParameter, P) 'reset the device, so we can use it again
                _presentParameter = P
                DeviceLost = False    'device is no longer lost!!!

                'Now recreate all your Pool_Default stuff, and your swapchain instances.

            Catch bug As DeviceLostException  'it is possible to lose the device while resetting it.
                'if it got lost again or not reset, do nothing
            End Try
        End Try

    End Sub
#End Region
    ''' <summary>
    ''' Hier zeichnen wir das Bild in den Backbuffer und erstellen das neue Bild auf den Bildschirm
    ''' </summary>
    Public Shared Function Updateframe() As Boolean
        'prüfen ob es den Device gibt
        If Grafikkarte Is Nothing Then Return False
        If DeviceLost Then
            AttemptRecovery() ' this is obvious, isn't it?
        End If
        If DeviceLost Then Return False
        'Bildschirm säuber
        Grafikkarte.Clear(ClearFlags.Target Or ClearFlags.ZBuffer, System.Drawing.Color.Black, 1.0F, 0)

        'Szene beginnen
        Grafikkarte.BeginScene()

        'Am Anfang mal die Kamera ausrichten.
        If Objektverwalter.Spielfeld IsNot Nothing Then
            With Objektverwalter.Spielfeld
                Grafikkarte.Transform.Projection = Matrix.PerspectiveFovLH(Math.PI / 4, Hauptmenü.MainMenü.MalPanel.Width / Hauptmenü.MainMenü.MalPanel.Height, 1, 1000)
                ''.KameraTarget = New Vector3(-17.125, 0, 9.9375)
                ' .Kamerahöhe= 70
                ' .KameraRichtung = 0
                ' .KameraPos = New Vector3(0, 70, -1)

                '.KameraTarget = New Vector3(-.BildschirmKooX / Hauptmenü.Feldbreite, 0, .BildschirmKooY / Hauptmenü.Feldbreite)
                ' .KameraHöhe += 1
                ' Grafikkarte.RenderState.Lighting = True
                Grafikkarte.Transform.View = Matrix.LookAtLH(.KameraPos, .KameraTarget, New Vector3(0, 1, 0))
                Grafikkarte.RenderState.FogEnable = False 'Äh die beiden False sind glaub ich so unnötig, aber egal, hauptsache wir haben mehr Code ;)
                ' Grafikkarte.RenderState.ZBufferEnable = False
            End With
        End If


        'wir teilen dem DirectX mit das wir nun 2D-Bilder zeichnen möchten
        Sprite.Begin(SpriteFlags.AlphaBlend)
     


        If Objektverwalter.Malen() = False Then
            Return False
        End If

        Sprite.End()
       
        If My.Settings.draw3D Then
            If My.Settings.Lichtmaus Then
            End If
            Dim mat As Matrix = Matrix.Identity
            mat.M41 = Lichtp.X
            mat.M42 = 0
            mat.M43 = Lichtp.Z
            Grafikkarte.Transform.World = mat
            'Box.DrawSubset(0)
        End If

        'Szene beenden
        Grafikkarte.EndScene()
        Try
            'Szene präsentieren
            Grafikkarte.Present()    'draw device contents to screen
        Catch e As Exception

            'AAACK! We lost the device!
            DeviceLost = True
        End Try
        Return True
    End Function
    Public Shared Sub fillRect(ByVal Rechteck As Rectangle, ByVal intColor As Color)
        If FilledTexture Is Nothing Then Exit Sub
        Dim sngRotation As Single = 0
        Grafikengine.recBild = Nothing
        Grafikengine.ptfPosition = New Drawing.Point(Rechteck.X, Rechteck.Y)
        With Grafikengine.szfScale
            .Height = Rechteck.Height
            .Width = Rechteck.Width
        End With
        Grafikengine.Sprite.Draw2D(FilledTexture, Grafikengine.recBild, Grafikengine.szfScale, Grafikengine.ptfRotCenter, sngRotation, Grafikengine.ptfPosition, intColor)
    End Sub
    Public Shared Sub fillRect(ByVal X As Integer, ByVal Y As Integer, ByVal Breite As Integer, ByVal Höhe As Integer, ByVal intColor As Color)
        If FilledTexture Is Nothing Then Exit Sub
        Dim sngRotation As Single = 0
        Grafikengine.recBild = Nothing
        Grafikengine.ptfPosition = New Drawing.Point(X, Y)
        With Grafikengine.szfScale
            .Height = Höhe
            .Width = Breite
        End With
        Grafikengine.Sprite.Draw2D(FilledTexture, Grafikengine.recBild, Grafikengine.szfScale, Grafikengine.ptfRotCenter, sngRotation, Grafikengine.ptfPosition, intColor)
    End Sub
    ''' <summary>
    ''' Malt eine Box im folgendem Muster, Ecken und Rand ungezoomt, Mitte ungezoomt
    ''' </summary>
    ''' <param name="Textur"></param>
    ''' <param name="Pos"></param>
    ''' <param name="OrgSize"></param>
    ''' <param name="RandBreite"></param>
    ''' <remarks></remarks>
    ''' 
    Public Shared Sub DrawBox(ByVal Textur As Texture, ByVal Pos As Point, ByVal OrgSize As Size, ByVal RandBreite As Integer, ByVal intcolorRand As Color, ByVal intcolorMitte As Color)
        DrawBox(Textur, Pos, OrgSize, OrgSize, RandBreite, intcolorRand, intcolorMitte)
    End Sub
    ''' <summary>
    ''' Malt eine Box im folgendem Muster, Ecken und Rand ungezoomt, Mitte gezoomt
    ''' </summary>
    ''' <param name="Textur"></param>
    ''' <param name="Pos"></param>
    ''' <param name="OrgSize"></param>
    ''' <param name="DesSize"></param>
    ''' <param name="RandBreite"></param>
    ''' <remarks></remarks>
    Public Shared Sub DrawBox(ByVal Textur As Texture, ByVal Pos As Point, ByVal OrgSize As Size, ByVal DesSize As Size, ByVal RandBreite As Integer, ByVal intcolorRand As Color)
        DrawBox(Textur, Pos, OrgSize, DesSize, RandBreite, intcolorRand, intcolorRand)
    End Sub
    ''' <summary>
    ''' Malt eine Box im folgendem Muster, Ecken und Rand ungezoomt, Mitte gezoomt
    ''' </summary>
    ''' <param name="Textur"></param>
    ''' <param name="Pos"></param>
    ''' <param name="OrgSize"></param>
    ''' <param name="DesSize"></param>
    ''' <param name="RandBreite"></param>
    ''' <remarks></remarks>
    Public Shared Sub DrawBox(ByVal Textur As Texture, ByVal Pos As Point, ByVal OrgSize As Size, ByVal DesSize As Size, ByVal RandBreite As Integer, ByVal intcolorRand As Color, ByVal intcolorMitte As Color)
        Dim sngrotation As Single = 0
        Grafikengine.ptfRotCenter = New Point
        'Linke Obere Ecke
        Grafikengine.ptfPosition = Pos
        With Grafikengine.recBild
            .X = 0 : .Width = RandBreite
            .Y = 0 : .Height = RandBreite
        End With
        Grafikengine.szfScale = Nothing
        Grafikengine.Sprite.Draw2D(Textur, Grafikengine.recBild, Grafikengine.szfScale, Grafikengine.ptfRotCenter, sngrotation, Grafikengine.ptfPosition, intcolorRand)
        'Oben Mitte
        Grafikengine.ptfPosition.X += RandBreite
        With Grafikengine.recBild
            .X = RandBreite : .Width = OrgSize.Width - RandBreite * 2
            .Y = 0 : .Height = RandBreite
        End With
        Grafikengine.szfScale.Width = DesSize.Width - RandBreite * 2
        Grafikengine.szfScale.Height = RandBreite
        Grafikengine.Sprite.Draw2D(Textur, Grafikengine.recBild, Grafikengine.szfScale, Grafikengine.ptfRotCenter, sngrotation, Grafikengine.ptfPosition, intcolorRand)
        'Rechte Obere Ecke
        Grafikengine.ptfPosition.X += DesSize.Width - RandBreite * 2
        With Grafikengine.recBild
            .X = OrgSize.Width - RandBreite : .Width = RandBreite
            .Y = 0 : .Height = RandBreite
        End With
        Grafikengine.szfScale = Nothing
        Grafikengine.Sprite.Draw2D(Textur, Grafikengine.recBild, Grafikengine.szfScale, Grafikengine.ptfRotCenter, sngrotation, Grafikengine.ptfPosition, intcolorRand)
        'Links Mitte
        Grafikengine.ptfPosition.X = Pos.X
        Grafikengine.ptfPosition.Y += RandBreite
        With Grafikengine.recBild
            .X = 0 : .Width = RandBreite
            .Y = RandBreite : .Height = OrgSize.Height - 2 * RandBreite
        End With
        Grafikengine.szfScale.Height = DesSize.Height - 2 * RandBreite
        Grafikengine.szfScale.Width = RandBreite
        Grafikengine.Sprite.Draw2D(Textur, Grafikengine.recBild, Grafikengine.szfScale, Grafikengine.ptfRotCenter, sngrotation, Grafikengine.ptfPosition, intcolorRand)
        'Mitte Mitte
        Grafikengine.ptfPosition.X += RandBreite
        With Grafikengine.recBild
            .X = RandBreite : .Width = OrgSize.Width - 2 * RandBreite
            .Y = RandBreite : .Height = OrgSize.Height - 2 * RandBreite
        End With
        Grafikengine.szfScale.Width = DesSize.Width - 2 * RandBreite
        Grafikengine.Sprite.Draw2D(Textur, Grafikengine.recBild, Grafikengine.szfScale, Grafikengine.ptfRotCenter, sngrotation, Grafikengine.ptfPosition, intcolorRand)
        'Links Mitte
        Grafikengine.ptfPosition.X += DesSize.Width - RandBreite * 2
        With Grafikengine.recBild
            .X = OrgSize.Width - RandBreite : .Width = RandBreite
            .Y = RandBreite : .Height = OrgSize.Height - 2 * RandBreite
        End With
        Grafikengine.szfScale.Width = RandBreite
        Grafikengine.Sprite.Draw2D(Textur, Grafikengine.recBild, Grafikengine.szfScale, Grafikengine.ptfRotCenter, sngrotation, Grafikengine.ptfPosition, intcolorRand)
        'Linke Untere Ecke
        Grafikengine.ptfPosition.X = Pos.X
        Grafikengine.ptfPosition.Y += DesSize.Height - RandBreite * 2
        With Grafikengine.recBild
            .X = 0 : .Width = RandBreite
            .Y = OrgSize.Height - RandBreite : .Height = RandBreite
        End With
        Grafikengine.szfScale = Nothing
        Grafikengine.Sprite.Draw2D(Textur, Grafikengine.recBild, Grafikengine.szfScale, Grafikengine.ptfRotCenter, sngrotation, Grafikengine.ptfPosition, intcolorRand)
        'Unten Mitte
        Grafikengine.ptfPosition.X += RandBreite
        With Grafikengine.recBild
            .X = RandBreite : .Width = OrgSize.Width - RandBreite * 2
        End With
        Grafikengine.szfScale.Width = DesSize.Width - RandBreite * 2
        Grafikengine.szfScale.Height = RandBreite
        Grafikengine.Sprite.Draw2D(Textur, Grafikengine.recBild, Grafikengine.szfScale, Grafikengine.ptfRotCenter, sngrotation, Grafikengine.ptfPosition, intcolorRand)
        'Rechte Untere Ecke
        Grafikengine.ptfPosition.X += DesSize.Width - RandBreite * 2
        With Grafikengine.recBild
            .X = OrgSize.Width - RandBreite : .Width = RandBreite
        End With
        Grafikengine.szfScale = Nothing
        Grafikengine.Sprite.Draw2D(Textur, Grafikengine.recBild, Grafikengine.szfScale, Grafikengine.ptfRotCenter, sngrotation, Grafikengine.ptfPosition, intcolorRand)
    End Sub
    Public Shared Sub DrawBox(ByVal Rechteck As Rectangle, ByVal Farbe As Color, ByVal Rand As Integer)
        Grafikengine.fillRect(New Rectangle(Rechteck.X, Rechteck.Y, Rechteck.Width, Rand), Farbe)
        Grafikengine.fillRect(New Rectangle(Rechteck.X, Rechteck.Y - Rand + Rechteck.Height, Rechteck.Width, Rand), Farbe)
        Grafikengine.fillRect(New Rectangle(Rechteck.X, Rechteck.Y, Rand, Rechteck.Height), Farbe)
        Grafikengine.fillRect(New Rectangle(Rechteck.X - Rand + Rechteck.Width, Rechteck.Y, Rand, Rechteck.Height), Farbe)
    End Sub
#End Region
#Region "Bilderverändern"

    ''' <summary>
    ''' Diese Funktion ändert die Farbe aller Pixel mit einer 
    ''' bestimmten Farben in eine neue Farbe um
    ''' </summary>
    ''' <param name="SourceImage">Das Bild dessen Pixel neu gezeichnet werden sollen</param>
    ''' <param name="OldColor">Die alte Farbe</param>
    ''' <param name="NewColor">Die neue Farbe</param>
    Public Shared Function Pixelneueinfärben(ByVal SourceImage As Image, ByVal OldColor As Color, ByVal NewColor As Color) As Bitmap
        Dim NewBitmap As New Bitmap(SourceImage.Width, SourceImage.Height)
        Dim CMap(0) As ColorMap

        CMap(0) = New ColorMap
        CMap(0).OldColor = OldColor
        CMap(0).NewColor = NewColor

        Dim ImgAttr As New ImageAttributes
        ImgAttr.SetRemapTable(CMap)

        Using G As Graphics = Graphics.FromImage(NewBitmap)
            G.DrawImage(SourceImage, New Rectangle(0, 0, SourceImage.Width, SourceImage.Height), 0, 0, SourceImage.Width, SourceImage.Height, GraphicsUnit.Pixel, ImgAttr)
        End Using

        Return NewBitmap
    End Function
    'Dieser Teil färbt alles um
    ''' <summary>
    ''' Farbton eines Bitmaps ändern
    ''' </summary>
    ''' <param name="InBitmap">Bitmap-Objekt</param>
    ''' <param name="Hue">Hue (0 bis 360, 0 oder 360 = Normal)</param>
    ''' <returns>Bitmap-Objekt</returns>
    Private Shared Function Farbwertverädern(ByVal InBitmap As Bitmap, Optional ByVal Hue As Single = 50) As Bitmap

        ' Min/Max
        If Hue < 0 Then Hue = 0
        If Hue > 360 Then Hue = 360

        Dim RedR As New Single
        Dim RedG As New Single
        Dim RedB As New Single
        Dim GreenR As New Single
        Dim GreenG As New Single
        Dim GreenB As New Single
        Dim BlueR As New Single
        Dim BlueG As New Single
        Dim BlueB As New Single
        'Sektor des Farbwertes
        Dim Sector As Integer = CInt(Hue) \ 60
        Hue = Hue / 60

        Select Case Sector

            Case 0

                RedR = 1 : GreenR = -Hue : BlueR = Hue
                RedG = Hue : GreenG = 1 : BlueG = -Hue
                RedB = -Hue : GreenB = Hue : BlueB = 1

            Case 1

                RedR = 2 - Hue : GreenR = Hue - 2 : BlueR = 1
                RedG = 1 : GreenG = 2 - Hue : BlueG = Hue - 2
                RedB = Hue - 2 : GreenB = 1 : BlueB = 2 - Hue

            Case 2

                RedR = 2 - Hue : GreenR = Hue - 2 : BlueR = 1
                RedG = 1 : GreenG = 2 - Hue : BlueG = Hue - 2
                RedB = Hue - 2 : GreenB = 1 : BlueB = 2 - Hue

            Case 3

                RedR = Hue - 4 : GreenR = 1 : BlueR = 4 - Hue
                RedG = 4 - Hue : GreenG = Hue - 4 : BlueG = 1
                RedB = 1 : GreenB = 4 - Hue : BlueB = Hue - 4

            Case 4

                RedR = Hue - 4 : GreenR = 1 : BlueR = 4 - Hue
                RedG = 4 - Hue : GreenG = Hue - 4 : BlueG = 1
                RedB = 1 : GreenB = 4 - Hue : BlueB = Hue - 4

            Case 5

                RedR = 1 : GreenR = 6 - Hue : BlueR = Hue - 6
                RedG = Hue - 6 : GreenG = 1 : BlueG = 6 - Hue
                RedB = 6 - Hue : GreenB = Hue - 6 : BlueB = 1

            Case 6

                RedR = 1 : GreenR = 0 : BlueR = 0
                RedG = 0 : GreenG = 1 : BlueG = 0
                RedB = 0 : GreenB = 0 : BlueB = 1
        End Select

        ' ColorMatrix erstellen
        Dim Matrix As New Imaging.ColorMatrix(New Single()() {New Single() {RedR, RedG, RedB, 0, 0}, New Single() {GreenR, GreenG, GreenB, 0, 0}, New Single() {BlueR, BlueG, BlueB, 0, 0}, New Single() {0, 0, 0, 1, 0}, New Single() {0, 0, 0, 0, 1}})

        ' neue Bitmap erstellen, das Bitmap das zurückgegeben wird
        Dim NewBmp As New Bitmap(InBitmap.Width, InBitmap.Height, Drawing.Imaging.PixelFormat.Format24bppRgb)


        ' ImageAttribute-Objekt erstellen
        Using ImageAttr As New Imaging.ImageAttributes()

            ' ColorMatrix für das ImageAttribute-Objekt setzen
            ImageAttr.SetColorMatrix(Matrix)

            ' Graphics-Objekt von NewBmp erstellen
            Using NewBmpGra As Graphics = Graphics.FromImage(NewBmp)

                ' InBitmap in das Graphics-Objekt zeichnen
                NewBmpGra.DrawImage(InBitmap, New Rectangle(0, 0, InBitmap.Width, InBitmap.Height), 0, 0, InBitmap.Width, InBitmap.Height, GraphicsUnit.Pixel, ImageAttr)

                'Graphics-Objekt löschen
            End Using

            ' ImageAttribute-Objekt löschen
        End Using

        Return NewBmp

    End Function
    ''' <summary>
    ''' Helligkeit eines Bitmaps ändern
    ''' </summary>
    ''' <param name="InBitmap">Bitmap-Objekt</param>
    ''' <param name="Helligkeit">Heligkeit (-1 bis 1) 0 = Normal</param>
    ''' <returns>Bitmap-Objekt</returns>
    Public Shared Function Helligkeitverändern(ByVal InBitmap As Bitmap, ByVal Helligkeit As Single) As Bitmap

        ' Min/Max
        If Helligkeit > 1 Then Helligkeit = 1
        If Helligkeit < -1 Then Helligkeit = -1


        ' Gammawert darf nicht = 0 sein (Bug in GDI+)
        Dim Gamma As Single = 1.0
        Dim Contrast As Single = 0.0
        ' Zur korrekten Darstellung:
        Dim Diff As Single = (Helligkeit / 2) - (Contrast / 2)

        ' ColorMatrix erstellen
        Dim Matrix As New Imaging.ColorMatrix(New Single()() {New Single() {1 + Contrast, 0, 0, 0, 0}, New Single() {0, 1 + Contrast, 0, 0, 0}, New Single() {0, 0, 1 + Contrast, 0, 0}, New Single() {0, 0, 0, 1 + Contrast, 0}, New Single() {Helligkeit + Diff, Helligkeit + Diff, Helligkeit + Diff, 0, 1}})
        'Neue Bitmap erstellen
        Dim NewBmp As New Bitmap(InBitmap.Width, InBitmap.Height, Drawing.Imaging.PixelFormat.Format24bppRgb)

        ' ImageAttribute-Objekt erstellen
        Using ImageAttr As New Imaging.ImageAttributes()

            ' ColorMatrix für das ImageAttribute-Objekt setzen
            ImageAttr.SetColorMatrix(Matrix)

            ' Gamma für das ImageAttribute-Objekt setzen
            ImageAttr.SetGamma(Gamma)

            ' Graphics-Objekt von NewBmp erstellen
            Using NewBmpGra As Graphics = Graphics.FromImage(NewBmp)

                ' InBitmap in das Graphics-Objekt zeichnen
                NewBmpGra.DrawImage(InBitmap, New Rectangle(0, 0, InBitmap.Width, InBitmap.Height), 0, 0, InBitmap.Width, InBitmap.Height, GraphicsUnit.Pixel, ImageAttr)

                'Graphics-Objekt löschen
            End Using

            ' ImageAttribute-Objekt löschen
        End Using

        Return NewBmp

    End Function
    'Ab hier steht eigenes Material
    ''' <summary>
    '''        Zerschneidet ein Bild in einzelne Bildteile
    ''' </summary>
    ''' <param name="Bild"></param>
    ''' <param name="AnzahlX">Die Anzahl der Bildteile in X-Richtung</param>
    ''' <param name="AnzahlY">Die Anzahl der Bildteile in Y-Richtung</param>
    ''' <returns>Gib einen Bitmap-Array zurück wobei der Array eindimensional und in YReihen gespalten ist</returns>
    Public Function Spriteserstellen(ByVal Bild As Bitmap, ByVal AnzahlX As Integer, ByVal AnzahlY As Integer)
        Dim Bilder() As Bitmap = {}
        'Der Array wird gespalten
        Array.Resize(Bilder, AnzahlX * AnzahlY)
        Dim Bildbreite As Integer = Bild.Width
        Dim Bildhöhe As Integer = Bild.Height
        Dim einzelBildbreite As Integer = Bild.Width / AnzahlX
        Dim einzelBildhöhe As Integer = Bild.Height / AnzahlY
        'Das Bild wird einmal durch gegangen
        For I = 0 To AnzahlY - 1
            For I2 = 0 To AnzahlX - 1

                'Das einzel Bild
                Dim einzelBild As New Bitmap(einzelBildbreite, einzelBildhöhe, Drawing.Imaging.PixelFormat.Format24bppRgb)
                For I3 = 0 To einzelBildhöhe - 1
                    For I4 = 0 To einzelBildbreite - 1
                        'Hier verändern wir den Pixel Punkt im Bitmap
                        einzelBild.SetPixel(I4, I3, Bild.GetPixel(I2 * einzelBildbreite + I4, I * einzelBildhöhe + I3))
                    Next
                Next
                Bilder(I * AnzahlX + I2) = einzelBild
            Next
        Next
        Return Bilder
    End Function
    ''' <summary>
    '''       Schneidet ein Bild aus und gibt es zurück
    ''' </summary>
    ''' <param name="Bild"></param>
    ''' <param name="AnzahlX">Die Anzahl der Bildteile in X-Richtung angefangen bei 1</param>
    ''' <param name="AnzahlY">Die Anzahl der Bildteile in Y-Richtung angefangen bei 1</param>
    ''' <param name="BildstelleX">Das wie vielte Bild in XRichtung angefangen bei 0</param>
    ''' <param name="BildstelleY">Das wie vielte Bild in YRichtung angefangen bei 0</param>
    ''' <returns>Gibt das gewünschte Bild zurück</returns>
    Public Function Spriteserstellen(ByVal Bild As Bitmap, ByVal AnzahlX As Integer, ByVal AnzahlY As Integer, ByVal BildstelleX As Integer, ByVal BildstelleY As Integer)
        Dim Bildbreite As Integer = Bild.Width
        Dim Bildhöhe As Integer = Bild.Height
        Dim einzelBildbreite As Integer = Bild.Width / AnzahlX
        Dim einzelBildhöhe As Integer = Bild.Height / AnzahlY
        'Das Bild wird einmal durch gegangen
        'Das einzel Bild
        Dim einzelBild As New Bitmap(einzelBildbreite, einzelBildhöhe, Drawing.Imaging.PixelFormat.Format24bppRgb)
        For I3 = 0 To einzelBildhöhe - 1
            For I4 = 0 To einzelBildbreite - 1
                'Hier verändern wir den Pixel Punkt im Bitmap
                einzelBild.SetPixel(I4, I3, Bild.GetPixel(BildstelleX * einzelBildbreite + I4, BildstelleY * einzelBildhöhe + I3))
            Next
        Next
        Return einzelBild
    End Function
    'Bild verändern
    ''' <summary>
    ''' Färbt ein Bild anhand einer Vorgegebenen Farbtabelle um
    ''' </summary>
    ''' <param name="Bild">Das Original Bild</param>
    ''' <param name="FarbtabelleimBild">Die Farbtabelle 1 Pixel Hoch beliebig Breit die Pixel müssen auch im Bild vorhanden sein</param>
    ''' <param name="Helligkeit">Um wie viel die Helligkeit verändert werden soll [-100 bis 100] 0=Normal </param>
    ''' <param name="Farbton">Der Farbton [0 bis 360] O und 360 = Normal</param>
    ''' <param name="FarbtabellefürdasBild">Die Farbtabelle mit der das Bild eingefärbt hat muss nicht mit der Farbe im Bild übereinstimmen wird anhand von Helligkeit und Farbton verändert</param>
    ''' <returns>Gibt das veränderte Bild als Bitmap zurück</returns>
    Public Shared Function Bildverändern(ByVal Bild As Bitmap, ByVal FarbtabelleimBild As Bitmap, ByVal Helligkeit As Integer, ByVal Farbton As Integer, ByVal FarbtabellefürdasBild As Bitmap)
        'Die Farbtabelle festlegen
        Dim neueFarbtabelle As Bitmap = Grafikengine.Farbwertverädern(FarbtabellefürdasBild, Farbton)
        neueFarbtabelle = Grafikengine.Helligkeitverändern(neueFarbtabelle, CSng(Helligkeit / 100))
        'So jetzt besitzen wir die Farbtabelle für das Bild

        'Das Bild
        Dim neueBitmap As Image = Bild
        'Die Farbtabelle wird in ein Bitmap umgeschrieben
        Dim Bitmapdateioriginal As Bitmap = FarbtabelleimBild
        Dim Bitmapdateineu As Bitmap = neueFarbtabelle

        'Die Originalen und neuen Farbvariablen
        Dim OriginalFarbwert As Color = Color.AliceBlue
        Dim NeuerFarbwert As Color = Color.AliceBlue
        'Die Farbtabelle wird einmal durchgegangen
        For I = 1 To FarbtabelleimBild.Width
            'Hier schauen wir uns das AltePixel und das neue Pixel genau an
            OriginalFarbwert = Bitmapdateioriginal.GetPixel(I - 1, 0)
            NeuerFarbwert = Bitmapdateineu.GetPixel(I - 1, 0)
            'Und jetzt schreiben wir das neue in das alte Bild rein 
            neueBitmap = Grafikengine.Pixelneueinfärben(neueBitmap, OriginalFarbwert, NeuerFarbwert)
        Next
        Return neueBitmap
    End Function

    'So und jetzt machen wir das Bild transparent
    ''' <summary>
    ''' Macht eine bestimmte Farbe transparent
    ''' </summary>
    ''' <param name="Bild">Das Bild das transparent gemacht werden soll</param>
    ''' <param name="Farbton">Die Farbe die Transparent gemacht wird</param>
    ''' <returns>Das veränderte Bild</returns>
    Public Function Transparent(ByVal Bild As Bitmap, ByVal Farbton As Color)
        Dim ZwischenBild As Bitmap = Bild
        ZwischenBild.MakeTransparent(Farbton)
        Bild = ZwischenBild
        Return Bild
    End Function
    'Hier Spiegeln wir ein Bild vertikal
    ''' <summary>
    ''' Spiegelt ein Bild an vertikal
    ''' </summary>
    ''' <param name="Bild">Das zu spiegelnde Bild</param>
    ''' <returns>Das gespiegelte Bild als Bitmap</returns>
    Public Function VertikalSpiegeln(ByVal Bild As Bitmap)
        Dim gespiegeltesBild As New Bitmap(Bild.Width, Bild.Height, Drawing.Imaging.PixelFormat.Format24bppRgb)
        Dim Breite As Integer = Bild.Width - 1
        For I = 0 To Bild.Width - 1
            For I2 = 0 To Bild.Height - 1
                gespiegeltesBild.SetPixel(Breite - I, I2, Bild.GetPixel(I, I2))
            Next
        Next
        Return gespiegeltesBild
    End Function
    ''' <summary>
    ''' Speichert ein Bild im angegeben Pfad
    ''' </summary>
    ''' <param name="Bild">Das zu speichernde Bild</param>
    ''' <param name="Name">Der Pfad unter dem das Spiel gespeichert wird</param>
    Public Sub Speichern(ByVal Bild As Image, ByVal Name As String)
        Bild.Save(Name + ".png", System.Drawing.Imaging.ImageFormat.Png)
    End Sub
    ''' <summary>
    ''' Diese Funktion lädt ein Bild
    ''' </summary>
    ''' <param name="Dateipfad">Der Pfad der Datei das geladen wird</param>
    ''' <returns>Das geladene Bild wird zurückgegeben</returns>
    Public Function Laden(ByVal Dateipfad As String)
        Dim Bild As Image = System.Drawing.Image.FromFile(Dateipfad)
        Return Bild
    End Function
    ''' <summary>
    ''' Schneidet einen Teil des Bildes aus
    ''' </summary>
    ''' <param name="Xlinks">Der Linke X Wert der Ecke</param>
    ''' <param name="Yoben">Der Obere Y Wert der Ecke</param>
    ''' <param name="XRechts">Der Rechte X Wert der Ecke</param>
    ''' <param name="Yunten">Der Untere Y Wert der Ecke</param>
    ''' <param name="Bild">Das Bild wo etwas ausgeschnitten werden soll</param>
    ''' <returns>Das ausgeschnittene Bild als Bitmap</returns>
    Public Function fAusschneiden(ByVal Xlinks As Integer, ByVal Yoben As Integer, ByVal XRechts As Integer, ByVal Yunten As Integer, ByVal Bild As Bitmap)
        Dim neuesBild As New Bitmap(XRechts - Xlinks, Yunten - Yoben, System.Drawing.Imaging.PixelFormat.Format24bppRgb)
        For I = 0 To XRechts - Xlinks - 1
            For I2 = 0 To Yunten - Yoben - 1
                neuesBild.SetPixel(I, I2, Bild.GetPixel(Xlinks + I, Yoben + I2))
            Next
        Next
        Return neuesBild
    End Function
#End Region

#Region "3D - Berechnung"
    Shared Lichtp As New Vector3
    Shared Box As Mesh
    Shared LichtKugel As Boolean = False
    Public Shared Mat As Material

    Shared Sub Lichtändern(ByVal Lichtf As Color)
        If Not Lichtf = Lichtfarbe Then 'Kann man das bei Farben machen? Vermutlich..
            Dim R, G, B As Integer
            R = Lichtf.R / 255 * (255 - Ambientfarbe.R)
            G = Lichtf.G / 255 * (255 - Ambientfarbe.G)
            B = Lichtf.B / 255 * (255 - Ambientfarbe.B)
            'If R > 255 - Ambientfarbe.R Then R = 255 - Ambientfarbe.R
            'If G > 255 - Ambientfarbe.G Then G = 255 - Ambientfarbe.G
            'If B > 255 - Ambientfarbe.B Then B = 255 - Ambientfarbe.B
            Lichtfarbe = Color.FromArgb(255, R, G, B)
            Grafikkarte.Lights(0).Diffuse = Lichtfarbe
            Grafikkarte.Lights(0).Update()
            Grafikkarte.Lights(1).Diffuse = Lichtfarbe
            Grafikkarte.Lights(1).Update()
        End If
    End Sub
    Shared Sub LichtartÄndern(ByVal Kugel As Boolean, Optional ByVal Reichweite As Single = 4)
        If Kugel Then
            Grafikkarte.Lights(0).Type = LightType.Point
            Grafikkarte.Lights(0).Range = Reichweite
            Grafikkarte.Lights(0).Attenuation0 = 0
            Grafikkarte.Lights(0).Attenuation1 = 0
            Grafikkarte.Lights(0).Attenuation2 = 0.5
            'Grafikkarte.Lights(0).Ambient = Color.White
            Mat.Emissive = Color.Black
            Mat.Ambient = Color.White
            Grafikkarte.Lights(1).Enabled = True
            Grafikkarte.Lights(1).Type = LightType.Directional
            Grafikkarte.Lights(1).Ambient = Ambientfarbe
            Grafikkarte.Lights(1).Diffuse = Color.Black
            Grafikkarte.Lights(1).Update()
            LichtKugel = True
        Else
            Grafikkarte.Lights(0).Type = LightType.Directional
            LichtKugel = False
            Mat.Emissive = Color.White
            Mat.Ambient = Color.Black
            Grafikkarte.Lights(1).Enabled = False
            Grafikkarte.Lights(1).Update()
            'Grafikkarte.Lights(0).Ambient = Color.Lime
        End If
        Grafikkarte.Lights(0).Update()
    End Sub
    Shared Sub setLichtPos(ByVal Pos As Vector3)
        If LichtKugel Then
            If Pos.X < 0 Then
                'Hmm.. außerhalb vom Spielfeld? dann ist das licht...
                Grafikkarte.Lights(0).Position = New Vector3(0, 1000, 0)
            Else
                Grafikkarte.Lights(0).Position = Pos
            End If
            Grafikkarte.Lights(0).Update()
        End If

        ' LichtartÄndern(False, 4)
    End Sub


    Shared Function Intersect(ByVal Msh As Mesh, ByVal x As Single, ByVal y As Single, ByVal mat As Matrix) As Single
        Dim Near As Vector3
        Dim Far As Vector3
        Return Intersect(Msh, x, y, mat, Near, Far)
    End Function
    Shared Function Intersect(ByVal Msh As Mesh, ByVal x As Single, ByVal y As Single, ByVal mat As Matrix, ByRef Near As Vector3, ByRef Far As Vector3) As Single
        If Msh Is Nothing Then Return 2

        Dim Closest As IntersectInformation
        Near = New Vector3(x, y, 0)
        Far = New Vector3(x, y, 1)

        '=======================================================
        'When doing the Unproject for the 'Near' and 'Far', the 
        'last parameter should be the world transformation matrix
        'for the MESH, not the device. If you use the device's 
        'matrix it will put the mesh's position at the origin of the world
        'Try adding another mesh and moving it around to see what I mean.
        Near.Unproject(Grafikkarte.Viewport, Grafikkarte.Transform.Projection, Grafikkarte.Transform.View, mat)
        Far.Unproject(Grafikkarte.Viewport, Grafikkarte.Transform.Projection, Grafikkarte.Transform.View, mat)
        Far.Subtract(Near)
        '=======================================================
        'Here is where you check for an intersection
        If Msh.Intersect(Near, Far, Closest) Then
            'Erwischt!
            If Closest.Dist > 1 Then
                ' Console.WriteLine("Ich dachte es geht nicht mehr als 1! War allerdings nur ne Vermutung, also doch nicht nearplane und farplane, sondern der tatsächliche abstand in Koordinaten?")
                CInt("Hallo").ToString()
            End If
            Return Closest.Dist
        Else
            'nicht getroffen, schnaps gesoffen!
            Return 2
        End If
    End Function
    Public Shared Function Intersect(ByVal x As Single, ByVal y As Single) As Point
        'Erstmal schauen, wie die Gerade der Maus aussieht.
        Dim Near As Vector3 = New Vector3(x, y, 0) 'Pos Vector
        Dim Far As Vector3 = New Vector3(x, y, 1) 'Dir Vector
        Near.Unproject(Grafikkarte.Viewport, Grafikkarte.Transform.Projection, Grafikkarte.Transform.View, Matrix.Identity)
        Far.Unproject(Grafikkarte.Viewport, Grafikkarte.Transform.Projection, Grafikkarte.Transform.View, Matrix.Identity)
        Far.Subtract(Near)

        Dim dist As Single
        Dim P As New Point(-1, -1)
        Dim distMin As Single = 2
        Dim MinPos, MinVec, pos, vec As Vector3
        For KooX = 0 To Objektverwalter.Spielfeld.Breite - 1
            For KooY = 0 To Objektverwalter.Spielfeld.Höhe - 1
                Dim Msh As Mesh = Nothing
                Dim mat As Matrix = Matrix.Identity
                mat.M41 = KooX
                mat.M43 = -KooY

                Dim G As ObjektGebäude = Objektverwalter.Spielfeld.Landschaften(KooX, KooY, 0).Gebäude
                If G IsNot Nothing Then
                    'Ein Gebäude!
                    Msh = ObjektLadeklasse.Gebäude3D.getMesh(G.GebäudeID)
                    dist = Intersect(Msh, x, y, mat, pos, vec)
                    If dist < distMin Then
                        'neuen Fafourit!
                        distMin = dist
                        P = New Point(KooX, KooY)
                        MinPos = pos
                        MinPos.X += mat.M41
                        MinPos.Y += mat.M42
                        MinPos.Z += mat.M43
                        MinVec = vec
                    End If
                End If

                'Dim E As ObjektEinheit = Objektverwalter.Spielfeld.Einheiten(KooX, KooY, 0)
                'If E IsNot Nothing Then
                '    'Eine Einheit!
                '    Msh = ObjektLadeklasse.Einheit3D.getMesh(E.EinheitenID)
                '    If Msh IsNot Nothing Then
                '        Dim MatE As Matrix = Matrix.RotationY(E.Rotation)
                '        Dim KooVec As Vector3 = Objektverwalter.LandschaftenBilder(Objektverwalter.Spielfeld.Landschaften(KooX, KooY, E.GetMap).ID).getFigurPos(E.getPosArt)
                '        MatE.M41 = KooX + KooVec.X
                '        MatE.M42 = KooVec.Y
                '        MatE.M43 = -KooY + KooVec.Z
                '        dist = Intersect(Msh, x, y, MatE, pos, vec)
                '        If dist < distMin Then
                '            'neuen Fafourit!
                '            distMin = dist
                '            P = New Point(KooX, KooY)
                '            MinPos = pos
                '            MinVec = vec
                '        End If
                '    End If
                'End If

                'vielleicht noch ein landschaftsmesh?
                Msh = Nothing ' Objektverwalter.LandschaftenBilder(Objektverwalter.Spielfeld.Landschaften(KooX, KooY, 0).ID).getMesh()
                If Msh Is Nothing Then 'bei keinem Landschaftsmesh, die box
                    Msh = Box 'wenn es kein Mesh gibt, dann halt die kleine Box, da dauert wenigstens das rechnen nicht so lange!
                    mat.M41 += 0.5
                    mat.M43 += 0.5
                End If
                dist = Intersect(Msh, x, y, mat, pos, vec)
                If dist < distMin Then
                    'neuen Fafourit!
                    distMin = dist
                    P = New Point(KooX, KooY)
                    MinPos = pos
                    MinPos.X += mat.M41
                    MinPos.Y += mat.M42
                    MinPos.Z += mat.M43
                    MinVec = vec
                End If
            Next
        Next
        If Not distMin > 1 Then
            'Ja was gefunden!
            Lichtp = Vector3.Add(MinPos, Vector3.Multiply(MinVec, -MinPos.Y / MinVec.Y))
            Lichtp = Vector3.Add(Near, Vector3.Multiply(Far, -Near.Y / Far.Y))
            Return P
        Else
            Return New Point(-1, -1)
        End If
    End Function
    'Public Shared Sub Intersect(ByVal x As Single, ByVal y As Single)
    '    Dim Near As Vector3
    '    Dim Far As Vector3
    '    Dim Closest As IntersectInformation
    '    Near = New Vector3(x, y, 0)
    '    Far = New Vector3(x, y, 1)
    '    '=======================================================
    '    'When doing the Unproject for the 'Near' and 'Far', the 
    '    'last parameter should be the world transformation matrix
    '    'for the MESH, not the device. If you use the device's 
    '    'matrix it will put the mesh's position at the origin of the world
    '    'Try adding another mesh and moving it around to see what I mean.
    '    Near.Unproject(Grafikkarte.Viewport, Grafikkarte.Transform.Projection, Grafikkarte.Transform.View, Grafikkarte.Transform.World)
    '    Far.Unproject(Grafikkarte.Viewport, Grafikkarte.Transform.Projection, Grafikkarte.Transform.View, Grafikkarte.Transform.World)
    '    Far.Subtract(Near)
    '    '=======================================================
    '    'Here is where you check for an intersection
    '    If Mesh.Intersect(Near, Far, Closest) Then
    '        'Erwischt!
    '    Else
    '        'nicht getroffen, schnaps gesoffen!
    '    End If
    'End Sub
#End Region
End Class
